package trading.algo.BullTask;

import java.util.Timer;
import java.util.TimerTask;

import trading.algo.MasterAlgo;
import trading.algo.MasterAlgoStartUpTask;
import trading.algo.OpenOrdersTask;
import trading.algo.TimerKillerTask;
import trading.algo.UpdateAccountValueTask;
import trading.algo.APIConnectivityTask.APIConnectMasterTask;
import trading.algo.initTask.HistoricalLowTask;
import trading.algo.initTask.LastClosePriceTask;
import trading.bo.DBAccessorBO;
import trading.bo.EmailAccessorBO;
import trading.bo.IBAccessorBO;
import trading.dataentry.MonitoredStocks;

public class AfterMarketHourBullTask extends TimerTask {
	
	private IBAccessorBO ibAccessorBO;
	private DBAccessorBO dbAccessorBO;
	private EmailAccessorBO emailAccessorBO;
	private MasterAlgo masterAlgo;
	
	public AfterMarketHourBullTask(IBAccessorBO ibAccessorBO, DBAccessorBO dbAccessorBO, EmailAccessorBO emailAccessorBO, MasterAlgo masterAlgo) {
		this.ibAccessorBO = ibAccessorBO;
		this.dbAccessorBO = dbAccessorBO;
		this.emailAccessorBO = emailAccessorBO;
		this.masterAlgo = masterAlgo;
	}

	@Override
	public void run() {

		Timer timer = new Timer();
		int taskID = 0;

        // try connect to IB, just in case
        APIConnectMasterTask apiConnectMasterTask = new APIConnectMasterTask(ibAccessorBO);
        timer.schedule(apiConnectMasterTask, taskID * 1000);
        taskID += APIConnectMasterTask.secondsNeeded();
        
		// sync the last closing price of stock tickers
		for (int i = 0; i < MonitoredStocks.TICKERS.values().length; i++, taskID += 3) {
			MonitoredStocks.TICKERS ticker = MonitoredStocks.TICKERS.values()[i];
			timer.schedule(new LastClosePriceTask(ticker.name(), ibAccessorBO),
					taskID * 1000);
		}

		// sync the stock historical low price
		for (int i = 0; i < MonitoredStocks.TICKERS.values().length; i++, taskID += 3) {
			MonitoredStocks.TICKERS ticker = MonitoredStocks.TICKERS.values()[i];
			timer.schedule(new HistoricalLowTask(ticker.name(), ibAccessorBO),
					taskID * 1000);
		}

		// sync the open orders
		timer.schedule(new OpenOrdersTask(ibAccessorBO, dbAccessorBO),
				taskID * 1000);
		taskID += 3;

		// sync the account status and portfolio positions
		timer.schedule(new UpdateAccountValueTask(ibAccessorBO, dbAccessorBO, true),
				taskID * 1000);
		taskID += 5;

		// sanity check if stock positions are well protected
		timer.schedule(new PositionProtectionCheckTask(ibAccessorBO,
				dbAccessorBO, emailAccessorBO), taskID * 1000);
		taskID += 45;

		// sync the open orders
		timer.schedule(new OpenOrdersTask(ibAccessorBO, dbAccessorBO),
				taskID * 1000);
		taskID += 5;
		
		// update trail amount
		timer.schedule(new UpdateTrailOrderMasterTask(this.ibAccessorBO, this.dbAccessorBO, this.emailAccessorBO, null), taskID * 1000);
		taskID += 35;
		
		// sync the open orders
		timer.schedule(new OpenOrdersTask(ibAccessorBO, dbAccessorBO),
				taskID * 1000);
		taskID += 3;
		
		// schedule for next trading day
		timer.schedule(new MasterAlgoStartUpTask(masterAlgo), taskID * 1000);
		taskID+=2;

		// kill the timer
		timer.schedule(new TimerKillerTask(timer), taskID * 1000);
	}

}
